package com.polarrose.wsf.validator;

import java.util.Collection;

public class LengthValidator implements Validator<Object> {

	private int minLength = 0;
	private int maxLength = Integer.MAX_VALUE;
	private boolean trim = true;
	private Validator<Object> collectionElementValidator;

	public String validate(Object o) {
		if (o == null) {
			if (maxLength == minLength && maxLength == 0) {
				return null;
			} else {
				return "Empty value is not permited.";
			}
		}
		if (o instanceof String) {
			String s = (String) o;
			if (trim) {
				s = s.trim();
			}
			if (s.length() < minLength) {
				return "String is shorter then " + minLength + " characters.";
			}
			if (s.length() > maxLength) {
				return "String is longer then " + maxLength + " characters.";
			}
			return null;
		} else if (o instanceof Collection) {
			Collection collection = (Collection) o;
			if (collection.size() < minLength) {
				return "Collection is smaller then " + minLength + " elements.";
			}
			if (collection.size() > maxLength) {
				return "Collection is bigger then " + maxLength + " elements.";
			}
			return validateElements(collection.toArray());
		} else if (o instanceof Object[]) {
			Object[] array = (Object[]) o;
			if (array.length < minLength) {
				return "Array is smaller then " + minLength + " elements.";
			}
			if (array.length > maxLength) {
				return "Array is bigger then " + maxLength + " elements.";
			}
			return validateElements(array);
		}
		throw new IllegalArgumentException("Only strings and collections are supported.");
	}

	private String validateElements(Object[] array) {
		if (collectionElementValidator == null || array.length == 0) {
			return null;
		}
		for (Object object : array) {
			String validateResults = collectionElementValidator.validate(object);
			if (validateResults != null) {
				return validateResults;
			}
		}
		return null;
	}

	public void setMaxLength(String maxLength) {
		this.maxLength = Integer.parseInt(maxLength);
		if (this.maxLength < 0) {
			throw new NumberFormatException("Only positive integers are allowed as maxLength");
		}
	}

	public void setMinLength(String minLength) {
		this.minLength = Integer.parseInt(minLength);
		if (this.minLength < 0) {
			throw new NumberFormatException("Only positive integers are allowed as minLength");
		}
	}
	public void setTrim(String trim) {
		this.trim = Boolean.parseBoolean(trim);
	}

	public void setCollectionElementValidator(String clazz) {
		try {
			this.collectionElementValidator = (Validator<Object>) Class.forName(clazz).newInstance();
		} catch (Exception e) {
			throw new RuntimeException("Could not instantionate collection element validator.", e);
		}
	}
}

